home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / usenet / volume4 / cribbage / part01 next >
Encoding:
Text File  |  1988-02-28  |  56.4 KB  |  2,137 lines

  1. Path: uunet!tektronix!tekgen!tekred!games
  2. From: games@tekred.TEK.COM
  3. Newsgroups: comp.sources.games
  4. Subject: v04i003:  cribbage - 4.3BSD cribbage game, Part01/02
  5. Message-ID: <2373@tekred.TEK.COM>
  6. Date: 31 Mar 88 21:54:15 GMT
  7. Sender: billr@tekred.TEK.COM
  8. Lines: 2126
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted by: bostic@okeeffe.Berkeley.EDU (Keith Bostic)
  12. Comp.sources.games: Volume 4, Issue 3
  13. Archive-name: cribbage/Part01
  14.  
  15.     [Here is the legal source for the 4.3BSD cribbage game. Thanks
  16.      to Keith Bostic at Berkeley for making this available.  -br]
  17.  
  18. #! /bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 1 (of 2)."
  25. # Contents:  README MANIFEST crib.c cribbage.6 cribbage.n cribcur.h
  26. #   io.c score.c
  27. # Wrapped by billr@saab on Thu Mar 31 13:51:52 1988
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f README -a "${1}" != "-c" ; then 
  30.   echo shar: Will not over-write existing file \"README\"
  31. else
  32. echo shar: Extracting \"README\" \(466 characters\)
  33. sed "s/^X//" >README <<'END_OF_README'
  34. XThe Makefiles for these games require the "dm" program to install
  35. X-- we've written a dungeon master program (hasn't everybody?) and they
  36. Xexpect to have it around.  They also require the "mkdep" program to
  37. Xcreate dependencies.  You probably want to note in the posting that
  38. Xthe problems exist, and everybody should hack the Makefile.
  39. X
  40. XYour posting should credit Earl Cohen with writing the logic for cribbage,
  41. Xand Ken Arnold with doing the screen interface.
  42. X
  43. X--keith
  44. END_OF_README
  45. if test 466 -ne `wc -c <README`; then
  46.     echo shar: \"README\" unpacked with wrong size!
  47. fi
  48. # end of overwriting check
  49. fi
  50. if test -f MANIFEST -a "${1}" != "-c" ; then 
  51.   echo shar: Will not over-write existing file \"MANIFEST\"
  52. else
  53. echo shar: Extracting \"MANIFEST\" \(564 characters\)
  54. sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
  55. X   File Name        Archive #    Description
  56. X-----------------------------------------------------------
  57. X MANIFEST                  1    This shipping list
  58. X Makefile                  2    
  59. X README                    1    
  60. X cards.c                   2    
  61. X crib.c                    1    
  62. X cribbage.6                1    
  63. X cribbage.h                2    
  64. X cribbage.n                1    
  65. X cribcur.h                 1    
  66. X deck.h                    2    
  67. X extern.c                  2    
  68. X io.c                      1    
  69. X macro                     2    
  70. X score.c                   1    
  71. X support.c                 2    
  72. END_OF_MANIFEST
  73. if test 564 -ne `wc -c <MANIFEST`; then
  74.     echo shar: \"MANIFEST\" unpacked with wrong size!
  75. fi
  76. # end of overwriting check
  77. fi
  78. if test -f crib.c -a "${1}" != "-c" ; then 
  79.   echo shar: Will not over-write existing file \"crib.c\"
  80. else
  81. echo shar: Extracting \"crib.c\" \(13125 characters\)
  82. sed "s/^X//" >crib.c <<'END_OF_crib.c'
  83. X/*
  84. X * Copyright (c) 1980 Regents of the University of California.
  85. X * All rights reserved.
  86. X *
  87. X * Redistribution and use in source and binary forms are permitted
  88. X * provided that this notice is preserved and that due credit is given
  89. X * to the University of California at Berkeley. The name of the University
  90. X * may not be used to endorse or promote products derived from this
  91. X * software without specific prior written permission. This software
  92. X * is provided ``as is'' without express or implied warranty.
  93. X */
  94. X
  95. X#ifndef lint
  96. Xchar copyright[] =
  97. X"@(#) Copyright (c) 1980 Regents of the University of California.\n\
  98. X All rights reserved.\n";
  99. X#endif /* not lint */
  100. X
  101. X#ifndef lint
  102. Xstatic char sccsid[] = "@(#)crib.c    5.2 (Berkeley) 3/10/88";
  103. X#endif /* not lint */
  104. X
  105. X# include    <curses.h>
  106. X# include    <signal.h>
  107. X# include    "deck.h"
  108. X# include    "cribbage.h"
  109. X# include    "cribcur.h"
  110. X
  111. X
  112. X# define    LOGFILE        "/usr/games/lib/criblog"
  113. X# define    INSTRCMD    "ul /usr/games/lib/crib.instr | more -f"
  114. X
  115. X
  116. Xmain(argc, argv)
  117. Xint    argc;
  118. Xchar    *argv[];
  119. X{
  120. X    register  char        *p;
  121. X    BOOLEAN            playing;
  122. X    char            *s;        /* for reading arguments */
  123. X    char            bust;        /* flag for arg reader */
  124. X    FILE            *f;
  125. X    FILE            *fopen();
  126. X    char            *getline();
  127. X    int            bye();
  128. X
  129. X    while (--argc > 0) {
  130. X        if ((*++argv)[0] != '-') {
  131. X        fprintf(stderr, "\n\ncribbage: usage is 'cribbage [-eqr]'\n");
  132. X        exit(1);
  133. X        }
  134. X        bust = FALSE;
  135. X        for (s = argv[0] + 1; *s != NULL; s++) {
  136. X        switch (*s) {
  137. X            case 'e':
  138. X            explain = TRUE;
  139. X            break;
  140. X            case 'q':
  141. X            quiet = TRUE;
  142. X            break;
  143. X            case 'r':
  144. X            rflag = TRUE;
  145. X            break;
  146. X            default:
  147. X            fprintf(stderr, "\n\ncribbage: usage is 'cribbage [-eqr]'\n");
  148. X            exit(2);
  149. X            break;
  150. X        }
  151. X        if (bust)
  152. X            break;
  153. X        }
  154. X    }
  155. X
  156. X    initscr();
  157. X    signal(SIGINT, bye);
  158. X    crmode();
  159. X    noecho();
  160. X    Playwin = subwin(stdscr, PLAY_Y, PLAY_X, 0, 0);
  161. X    Tablewin = subwin(stdscr, TABLE_Y, TABLE_X, 0, PLAY_X);
  162. X    Compwin = subwin(stdscr, COMP_Y, COMP_X, 0, TABLE_X + PLAY_X);
  163. X    Msgwin = subwin(stdscr, MSG_Y, MSG_X, Y_MSG_START, SCORE_X + 1);
  164. X    leaveok(Playwin, TRUE);
  165. X    leaveok(Tablewin, TRUE);
  166. X    leaveok(Compwin, TRUE);
  167. X    clearok(stdscr, FALSE);
  168. X
  169. X    if (!quiet) {
  170. X        msg("Do you need instructions for cribbage? ");
  171. X        if (getuchar() == 'Y') {
  172. X        endwin();
  173. X        fflush(stdout);
  174. X        system(INSTRCMD);
  175. X        crmode();
  176. X        noecho();
  177. X        clear();
  178. X        refresh();
  179. X        msg("For the rules of this program, do \"man cribbage\"");
  180. X        }
  181. X    }
  182. X    playing = TRUE;
  183. X    do {
  184. X        wclrtobot(Msgwin);
  185. X        msg(quiet ? "L or S? " : "Long (to 121) or Short (to 61)? ");
  186. X        if (glimit == SGAME)
  187. X        glimit = (getuchar() == 'L' ? LGAME : SGAME);
  188. X        else
  189. X        glimit = (getuchar() == 'S' ? SGAME : LGAME);
  190. X        game();
  191. X        msg("Another game? ");
  192. X        playing = (getuchar() == 'Y');
  193. X    } while (playing);
  194. X
  195. X    if ((f = fopen(LOGFILE, "a")) != NULL) {
  196. X        fprintf(f, "Won %5.5d, Lost %5.5d\n",  cgames, pgames);
  197. X        fclose(f);
  198. X    }
  199. X
  200. X    bye();
  201. X}
  202. X
  203. X/*
  204. X * makeboard:
  205. X *    Print out the initial board on the screen
  206. X */
  207. Xmakeboard()
  208. X{
  209. X    mvaddstr(SCORE_Y + 0, SCORE_X, "+---------------------------------------+");
  210. X    mvaddstr(SCORE_Y + 1, SCORE_X, "|  Score:   0     YOU                   |");
  211. X    mvaddstr(SCORE_Y + 2, SCORE_X, "| *.....:.....:.....:.....:.....:.....  |");
  212. X    mvaddstr(SCORE_Y + 3, SCORE_X, "| *.....:.....:.....:.....:.....:.....  |");
  213. X    mvaddstr(SCORE_Y + 4, SCORE_X, "|                                       |");
  214. X    mvaddstr(SCORE_Y + 5, SCORE_X, "| *.....:.....:.....:.....:.....:.....  |");
  215. X    mvaddstr(SCORE_Y + 6, SCORE_X, "| *.....:.....:.....:.....:.....:.....  |");
  216. X    mvaddstr(SCORE_Y + 7, SCORE_X, "|  Score:   0      ME                   |");
  217. X    mvaddstr(SCORE_Y + 8, SCORE_X, "+---------------------------------------+");
  218. X    gamescore();
  219. X}
  220. X
  221. X/*
  222. X * gamescore:
  223. X *    Print out the current game score
  224. X */
  225. Xgamescore()
  226. X{
  227. X    extern int    Lastscore[];
  228. X
  229. X    if (pgames || cgames) {
  230. X        mvprintw(SCORE_Y + 1, SCORE_X + 28, "Games: %3d", pgames);
  231. X        mvprintw(SCORE_Y + 7, SCORE_X + 28, "Games: %3d", cgames);
  232. X    }
  233. X    Lastscore[0] = -1;
  234. X    Lastscore[1] = -1;
  235. X}
  236. X
  237. X/*
  238. X * game:
  239. X *    Play one game up to glimit points.  Actually, we only ASK the
  240. X *    player what card to turn.  We do a random one, anyway.
  241. X */
  242. Xgame()
  243. X{
  244. X    register int        i, j;
  245. X    BOOLEAN            flag;
  246. X    BOOLEAN            compcrib;
  247. X
  248. X    makeboard();
  249. X    refresh();
  250. X    makedeck(deck);
  251. X    shuffle(deck);
  252. X    if (gamecount == 0) {
  253. X        flag = TRUE;
  254. X        do {
  255. X        if (!rflag) {                /* player cuts deck */
  256. X            msg(quiet ? "Cut for crib? " :
  257. X            "Cut to see whose crib it is -- low card wins? ");
  258. X            getline();
  259. X        }
  260. X        i = (rand() >> 4) % CARDS;        /* random cut */
  261. X        do {                    /* comp cuts deck */
  262. X            j = (rand() >> 4) % CARDS;
  263. X        } while (j == i);
  264. X        addmsg(quiet ? "You cut " : "You cut the ");
  265. X        msgcard(deck[i], FALSE);
  266. X        endmsg();
  267. X        addmsg(quiet ? "I cut " : "I cut the ");
  268. X        msgcard(deck[j], FALSE);
  269. X        endmsg();
  270. X        flag = (deck[i].rank == deck[j].rank);
  271. X        if (flag) {
  272. X            msg(quiet ? "We tied..." :
  273. X            "We tied and have to try again...");
  274. X            shuffle(deck);
  275. X            continue;
  276. X        }
  277. X        else
  278. X            compcrib = (deck[i].rank > deck[j].rank);
  279. X        } while (flag);
  280. X    }
  281. X    else {
  282. X        werase(Tablewin);
  283. X        wrefresh(Tablewin);
  284. X        werase(Compwin);
  285. X        wrefresh(Compwin);
  286. X        msg("Loser (%s) gets first crib",  (iwon ? "you" : "me"));
  287. X        compcrib = !iwon;
  288. X    }
  289. X
  290. X    pscore = cscore = 0;
  291. X    flag = TRUE;
  292. X    do {
  293. X        shuffle(deck);
  294. X        flag = !playhand(compcrib);
  295. X        compcrib = !compcrib;
  296. X    } while (flag);
  297. X    ++gamecount;
  298. X    if (cscore < pscore) {
  299. X        if (glimit - cscore > 60) {
  300. X        msg("YOU DOUBLE SKUNKED ME!");
  301. X        pgames += 4;
  302. X        }
  303. X        else if (glimit - cscore > 30) {
  304. X        msg("YOU SKUNKED ME!");
  305. X        pgames += 2;
  306. X        }
  307. X        else {
  308. X        msg("YOU WON!");
  309. X        ++pgames;
  310. X        }
  311. X        iwon = FALSE;
  312. X    }
  313. X    else {
  314. X        if (glimit - pscore > 60) {
  315. X        msg("I DOUBLE SKUNKED YOU!");
  316. X        cgames += 4;
  317. X        }
  318. X        else if (glimit - pscore > 30) {
  319. X        msg("I SKUNKED YOU!");
  320. X        cgames += 2;
  321. X        }
  322. X        else {
  323. X        msg("I WON!");
  324. X        ++cgames;
  325. X        }
  326. X        iwon = TRUE;
  327. X    }
  328. X    gamescore();
  329. X}
  330. X
  331. X/*
  332. X * playhand:
  333. X *    Do up one hand of the game
  334. X */
  335. Xplayhand(mycrib)
  336. XBOOLEAN        mycrib;
  337. X{
  338. X    register int        deckpos;
  339. X    extern char        Msgbuf[];
  340. X
  341. X    werase(Compwin);
  342. X
  343. X    knownum = 0;
  344. X    deckpos = deal(mycrib);
  345. X    sorthand(chand, FULLHAND);
  346. X    sorthand(phand, FULLHAND);
  347. X    makeknown(chand, FULLHAND);
  348. X    prhand(phand, FULLHAND, Playwin, FALSE);
  349. X    discard(mycrib);
  350. X    if (cut(mycrib, deckpos))
  351. X        return TRUE;
  352. X    if (peg(mycrib))
  353. X        return TRUE;
  354. X    werase(Tablewin);
  355. X    wrefresh(Tablewin);
  356. X    if (score(mycrib))
  357. X        return TRUE;
  358. X    return FALSE;
  359. X}
  360. X
  361. X
  362. X
  363. X/*
  364. X * deal cards to both players from deck
  365. X */
  366. X
  367. Xdeal( mycrib )
  368. X{
  369. X    register  int        i, j;
  370. X
  371. X    j = 0;
  372. X    for( i = 0; i < FULLHAND; i++ )  {
  373. X        if( mycrib )  {
  374. X        phand[i] = deck[j++];
  375. X        chand[i] = deck[j++];
  376. X        }
  377. X        else  {
  378. X        chand[i] = deck[j++];
  379. X        phand[i] = deck[j++];
  380. X        }
  381. X    }
  382. X    return( j );
  383. X}
  384. X
  385. X/*
  386. X * discard:
  387. X *    Handle players discarding into the crib...
  388. X * Note: we call cdiscard() after prining first message so player doesn't wait
  389. X */
  390. Xdiscard(mycrib)
  391. XBOOLEAN        mycrib;
  392. X{
  393. X    register char    *prompt;
  394. X    CARD        crd;
  395. X
  396. X    prcrib(mycrib, TRUE);
  397. X    prompt = (quiet ? "Discard --> " : "Discard a card --> ");
  398. X    cdiscard(mycrib);            /* puts best discard at end */
  399. X    crd = phand[infrom(phand, FULLHAND, prompt)];
  400. X    remove(crd, phand, FULLHAND);
  401. X    prhand(phand, FULLHAND, Playwin, FALSE);
  402. X    crib[0] = crd;
  403. X/* next four lines same as last four except for cdiscard() */
  404. X    crd = phand[infrom(phand, FULLHAND - 1, prompt)];
  405. X    remove(crd, phand, FULLHAND - 1);
  406. X    prhand(phand, FULLHAND, Playwin, FALSE);
  407. X    crib[1] = crd;
  408. X    crib[2] = chand[4];
  409. X    crib[3] = chand[5];
  410. X    chand[4].rank = chand[4].suit = chand[5].rank = chand[5].suit = EMPTY;
  411. X}
  412. X
  413. X/*
  414. X * cut:
  415. X *    Cut the deck and set turnover.  Actually, we only ASK the
  416. X *    player what card to turn.  We do a random one, anyway.
  417. X */
  418. Xcut(mycrib, pos)
  419. XBOOLEAN        mycrib;
  420. Xint        pos;
  421. X{
  422. X    register int        i, cardx;
  423. X    BOOLEAN            win = FALSE;
  424. X
  425. X    if (mycrib) {
  426. X        if (!rflag) {            /* random cut */
  427. X        msg(quiet ? "Cut the deck? " :
  428. X            "How many cards down do you wish to cut the deck? ");
  429. X        getline();
  430. X        }
  431. X        i = (rand() >> 4) % (CARDS - pos);
  432. X        turnover = deck[i + pos];
  433. X        addmsg(quiet ? "You cut " : "You cut the ");
  434. X        msgcard(turnover, FALSE);
  435. X        endmsg();
  436. X        if (turnover.rank == JACK) {
  437. X        msg("I get two for his heels");
  438. X        win = chkscr(&cscore,2 );
  439. X        }
  440. X    }
  441. X    else {
  442. X        i = (rand() >> 4) % (CARDS - pos) + pos;
  443. X        turnover = deck[i];
  444. X        addmsg(quiet ? "I cut " : "I cut the ");
  445. X        msgcard(turnover, FALSE);
  446. X        endmsg();
  447. X        if (turnover.rank == JACK) {
  448. X        msg("You get two for his heels");
  449. X        win = chkscr(&pscore, 2);
  450. X        }
  451. X    }
  452. X    makeknown(&turnover, 1);
  453. X    prcrib(mycrib, FALSE);
  454. X    return win;
  455. X}
  456. X
  457. X/*
  458. X * prcrib:
  459. X *    Print out the turnover card with crib indicator
  460. X */
  461. Xprcrib(mycrib, blank)
  462. XBOOLEAN        mycrib, blank;
  463. X{
  464. X    register int    y, cardx;
  465. X
  466. X    if (mycrib)
  467. X        cardx = CRIB_X;
  468. X    else
  469. X        cardx = 0;
  470. X
  471. X    mvaddstr(CRIB_Y, cardx + 1, "CRIB");
  472. X    prcard(stdscr, CRIB_Y + 1, cardx, turnover, blank);
  473. X
  474. X    if (mycrib)
  475. X        cardx = 0;
  476. X    else
  477. X        cardx = CRIB_X;
  478. X
  479. X    for (y = CRIB_Y; y <= CRIB_Y + 5; y++)
  480. X        mvaddstr(y, cardx, "       ");
  481. X}
  482. X
  483. X/*
  484. X * peg:
  485. X *    Handle all the pegging...
  486. X */
  487. X
  488. Xstatic CARD        Table[14];
  489. X
  490. Xstatic int        Tcnt;
  491. X
  492. Xpeg(mycrib)
  493. XBOOLEAN        mycrib;
  494. X{
  495. X    static CARD        ch[CINHAND], ph[CINHAND];
  496. X    CARD            crd;
  497. X    register int        i, j, k;
  498. X    register int        l;
  499. X    register int        cnum, pnum, sum;
  500. X    register BOOLEAN    myturn, mego, ugo, last, played;
  501. X
  502. X    cnum = pnum = CINHAND;
  503. X    for (i = 0; i < CINHAND; i++) {        /* make copies of hands */
  504. X        ch[i] = chand[i];
  505. X        ph[i] = phand[i];
  506. X    }
  507. X    Tcnt = 0;            /* index to table of cards played */
  508. X    sum = 0;            /* sum of cards played */
  509. X    mego = ugo = FALSE;
  510. X    myturn = !mycrib;
  511. X    for (;;) {
  512. X        last = TRUE;                /* enable last flag */
  513. X        prhand(ph, pnum, Playwin, FALSE);
  514. X        prhand(ch, cnum, Compwin, TRUE);
  515. X        prtable(sum);
  516. X        if (myturn) {                /* my tyrn to play */
  517. X        if (!anymove(ch, cnum, sum)) {        /* if no card to play */
  518. X            if (!mego && cnum) {        /* go for comp? */
  519. X            msg("GO");
  520. X            mego = TRUE;
  521. X            }
  522. X            if (anymove(ph, pnum, sum))        /* can player move? */
  523. X            myturn = !myturn;
  524. X            else {                /* give him his point */
  525. X            msg(quiet ? "You get one" : "You get one point");
  526. X            if (chkscr(&pscore, 1))
  527. X                return TRUE;
  528. X            sum = 0;
  529. X            mego = ugo = FALSE;
  530. X            Tcnt = 0;
  531. X            }
  532. X        }
  533. X        else {
  534. X            played = TRUE;
  535. X            j = -1;
  536. X            k = 0;
  537. X            for (i = 0; i < cnum; i++) {    /* maximize score */
  538. X            l = pegscore(ch[i], Table, Tcnt, sum);
  539. X            if (l > k) {
  540. X                k = l;
  541. X                j = i;
  542. X            }
  543. X            }
  544. X            if (j < 0)                /* if nothing scores */
  545. X            j = cchose(ch, cnum, sum);
  546. X            crd = ch[j];
  547. X            remove(crd, ch, cnum--);
  548. X            sum += VAL(crd.rank);
  549. X            Table[Tcnt++] = crd;
  550. X            if (k > 0) {
  551. X            addmsg(quiet ? "I get %d playing " :
  552. X                "I get %d points playing ", k);
  553. X            msgcard(crd, FALSE);
  554. X            endmsg();
  555. X            if (chkscr(&cscore, k))
  556. X                return TRUE;
  557. X            }
  558. X            myturn = !myturn;
  559. X        }
  560. X        }
  561. X        else {
  562. X        if (!anymove(ph, pnum, sum)) {        /* can player move? */
  563. X            if (!ugo && pnum) {            /* go for player */
  564. X            msg("You have a GO");
  565. X            ugo = TRUE;
  566. X            }
  567. X            if (anymove(ch, cnum, sum))        /* can computer play? */
  568. X            myturn = !myturn;
  569. X            else {
  570. X            msg(quiet ? "I get one" : "I get one point");
  571. X            do_wait();
  572. X            if (chkscr(&cscore, 1))
  573. X                return TRUE;
  574. X            sum = 0;
  575. X            mego = ugo = FALSE;
  576. X            Tcnt = 0;
  577. X            }
  578. X        }
  579. X        else {                    /* player plays */
  580. X            played = FALSE;
  581. X            if (pnum == 1) {
  582. X            crd = ph[0];
  583. X            msg("You play your last card");
  584. X            }
  585. X            else
  586. X            for (;;) {
  587. X                prhand(ph, pnum, Playwin, FALSE);
  588. X                crd = ph[infrom(ph, pnum, "Your play: ")];
  589. X                if (sum + VAL(crd.rank) <= 31)
  590. X                break;
  591. X                else
  592. X                msg("Total > 31 -- try again");
  593. X            }
  594. X            makeknown(&crd, 1);
  595. X            remove(crd, ph, pnum--);
  596. X            i = pegscore(crd, Table, Tcnt, sum);
  597. X            sum += VAL(crd.rank);
  598. X            Table[Tcnt++] = crd;
  599. X            if (i > 0) {
  600. X            msg(quiet ? "You got %d" : "You got %d points", i);
  601. X            if (chkscr(&pscore, i))
  602. X                return TRUE;
  603. X            }
  604. X            myturn = !myturn;
  605. X        }
  606. X        }
  607. X        if (sum >= 31) {
  608. X        if (!myturn)
  609. X            do_wait();
  610. X        sum = 0;
  611. X        mego = ugo = FALSE;
  612. X        Tcnt = 0;
  613. X        last = FALSE;                /* disable last flag */
  614. X        }
  615. X        if (!pnum && !cnum)
  616. X        break;                    /* both done */
  617. X    }
  618. X    prhand(ph, pnum, Playwin, FALSE);
  619. X    prhand(ch, cnum, Compwin, TRUE);
  620. X    prtable(sum);
  621. X    if (last)
  622. X        if (played) {
  623. X        msg(quiet ? "I get one for last" : "I get one point for last");
  624. X        do_wait();
  625. X        if (chkscr(&cscore, 1))
  626. X            return TRUE;
  627. X        }
  628. X        else {
  629. X        msg(quiet ? "You get one for last" :
  630. X                "You get one point for last");
  631. X        if (chkscr(&pscore, 1))
  632. X            return TRUE;
  633. X        }
  634. X    return FALSE;
  635. X}
  636. X
  637. X/*
  638. X * prtable:
  639. X *    Print out the table with the current score
  640. X */
  641. Xprtable(score)
  642. Xint    score;
  643. X{
  644. X    prhand(Table, Tcnt, Tablewin, FALSE);
  645. X    mvwprintw(Tablewin, (Tcnt + 2) * 2, Tcnt + 1, "%2d", score);
  646. X    wrefresh(Tablewin);
  647. X}
  648. X
  649. X/*
  650. X * score:
  651. X *    Handle the scoring of the hands
  652. X */
  653. Xscore(mycrib)
  654. XBOOLEAN        mycrib;
  655. X{
  656. X    sorthand(crib, CINHAND);
  657. X    if (mycrib) {
  658. X        if (plyrhand(phand, "hand"))
  659. X        return TRUE;
  660. X        if (comphand(chand, "hand"))
  661. X        return TRUE;
  662. X        do_wait();
  663. X        if (comphand(crib, "crib"))
  664. X        return TRUE;
  665. X    }
  666. X    else {
  667. X        if (comphand(chand, "hand"))
  668. X        return TRUE;
  669. X        if (plyrhand(phand, "hand"))
  670. X        return TRUE;
  671. X        if (plyrhand(crib, "crib"))
  672. X        return TRUE;
  673. X    }
  674. X    return FALSE;
  675. X}
  676. END_OF_crib.c
  677. if test 13125 -ne `wc -c <crib.c`; then
  678.     echo shar: \"crib.c\" unpacked with wrong size!
  679. fi
  680. # end of overwriting check
  681. fi
  682. if test -f cribbage.6 -a "${1}" != "-c" ; then 
  683.   echo shar: Will not over-write existing file \"cribbage.6\"
  684. else
  685. echo shar: Extracting \"cribbage.6\" \(4611 characters\)
  686. sed "s/^X//" >cribbage.6 <<'END_OF_cribbage.6'
  687. X.\" Copyright (c) 1980 Regents of the University of California.
  688. X.\" All rights reserved.
  689. X.\"
  690. X.\" Redistribution and use in source and binary forms are permitted
  691. X.\" provided that this notice is preserved and that due credit is given
  692. X.\" to the University of California at Berkeley. The name of the University
  693. X.\" may not be used to endorse or promote products derived from this
  694. X.\" software without specific prior written permission. This software
  695. X.\" is provided ``as is'' without express or implied warranty.
  696. X.\"
  697. X.\"    @(#)cribbage.6    6.3 (Berkeley) 3/10/88
  698. X.\"
  699. X.TH CRIBBAGE 6 "March 10, 1988"
  700. X.UC 4
  701. X.SH NAME
  702. Xcribbage \- the card game cribbage
  703. X.SH SYNOPSIS
  704. X.B /usr/games/cribbage
  705. X[
  706. X.B \-req
  707. X]
  708. X.I name ...
  709. X.SH DESCRIPTION
  710. X.I Cribbage
  711. Xplays the card game cribbage, with the program playing one hand
  712. Xand the user the other.  The program will initially ask the user if
  713. Xthe rules of the game are needed \- if so, it will print out
  714. Xthe appropriate section from
  715. X.I According to Hoyle
  716. Xwith
  717. X.I more (I).
  718. X.PP
  719. X.I Cribbage
  720. Xoptions include:
  721. X.TP
  722. X.B \-e
  723. XWhen the player makes a mistake scoring his hand or crib, provide an
  724. Xexplanation of the correct score.  (This is especially useful for
  725. Xbeginning players.)
  726. X.TP
  727. X.B \-q
  728. XPrint a shorter form of all messages \- this is only recommended for
  729. Xusers who have played the game without specifying this option.
  730. X.TP
  731. X.B \-r
  732. XInstead of asking the player to cut the deck, the program will randomly
  733. Xcut the deck.
  734. X.PP
  735. X.I Cribbage
  736. Xfirst asks the player whether he wishes to play a short game
  737. X(\*(lqonce around\*(rq, to 61) or a long game (\*(lqtwice around\*(rq, to 121).  A
  738. Xresponse of `s' will result in a short game, any other response will
  739. Xplay a long game.
  740. X.PP
  741. XAt the start of the first game, the program
  742. Xasks the player to cut the deck to determine who gets the
  743. Xfirst crib.  The user should respond with a number between 0 and
  744. X51, indicating how many cards down the deck is to be cut.  The player
  745. Xwho cuts the lower ranked card gets the first crib.
  746. XIf more than one game is played, the
  747. Xloser of the previous game gets the first crib in the current game.
  748. X.PP
  749. XFor each hand, the program first prints the player's hand,
  750. Xwhose crib it is, and then asks the player
  751. Xto discard two cards into the crib.  The cards are prompted for
  752. Xone per line, and are typed as explained below.
  753. X.PP
  754. XAfter discarding, the program cuts the deck (if it is the player's
  755. Xcrib) or asks the player to cut the deck (if it's its crib); in the latter
  756. Xcase, the appropriate response is a number from 0 to 39 indicating
  757. Xhow far down the remaining 40 cards are to be cut.
  758. X.PP
  759. XAfter cutting the deck, play starts with the non-dealer (the person
  760. Xwho doesn't have the crib) leading the first card.
  761. XPlay continues, as per cribbage, until all cards are exhausted.  The
  762. Xprogram keeps track of the scoring of all points and the total of
  763. Xthe cards on the table.
  764. X.PP
  765. XAfter play, the hands are scored.  The program requests the player to
  766. Xscore his hand (and the crib, if it is his) by printing out the
  767. Xappropriate cards (and the cut card enclosed in brackets).
  768. XPlay continues until one player reaches the game limit (61 or 121).
  769. X.PP
  770. XA carriage return when a numeric input is expected is equivalent
  771. Xto typing the lowest legal value; when cutting the deck this
  772. Xis equivalent to choosing the top card.
  773. X.PP
  774. XCards are specified as rank followed by suit.  The ranks may be specified
  775. Xas one of:
  776. X`a', `2', `3', `4', `5', `6', `7', `8', `9', `t', `j', `q', and `k',
  777. Xor alternatively, one of: \*(lqace\*(rq, \*(lqtwo\*(rq, \*(lqthree\*(rq, \*(lqfour\*(rq, \*(lqfive\*(rq, \*(lqsix\*(rq,
  778. X\*(lqseven\*(rq, \*(lqeight\*(rq, \*(lqnine\*(rq, \*(lqten\*(rq, \*(lqjack\*(rq, \*(lqqueen\*(rq, and \*(lqking\*(rq.
  779. XSuits may be specified as: `s', `h', `d', and `c', or alternatively as:
  780. X\*(lqspades\*(rq, \*(lqhearts\*(rq, \*(lqdiamonds\*(rq, and \*(lqclubs\*(rq.
  781. XA card may be specified as: <rank> \*(lq \*(rq <suit>, or: <rank> \*(lq of \*(rq <suit>.
  782. XIf the single letter rank and suit designations are used, the space
  783. Xseparating the suit and rank may be left out.  Also, if only one card
  784. Xof the desired rank is playable, typing the rank is sufficient.
  785. XFor example, if your hand was \*(lq2H, 4D, 5C, 6H, JC, KD\*(rq and it was
  786. Xdesired to discard the king of diamonds, any of the following could be typed:
  787. X\*(lqk\*(rq, \*(lqking\*(rq, \*(lqkd\*(rq, \*(lqk d\*(rq, \*(lqk of d\*(rq, \*(lqking d\*(rq, \*(lqking of d\*(rq, \*(lqk diamonds\*(rq,
  788. X\*(lqk of diamonds\*(rq, \*(lqking diamonds\*(rq, or \*(lqking of diamonds\*(rq.
  789. X.SH FILES
  790. X.ta 2i
  791. X/usr/games/cribbage
  792. X.SH AUTHORS
  793. XEarl T. Cohen wrote the logic.
  794. XKen Arnold added the screen oriented interface.
  795. END_OF_cribbage.6
  796. if test 4611 -ne `wc -c <cribbage.6`; then
  797.     echo shar: \"cribbage.6\" unpacked with wrong size!
  798. fi
  799. # end of overwriting check
  800. fi
  801. if test -f cribbage.n -a "${1}" != "-c" ; then 
  802.   echo shar: Will not over-write existing file \"cribbage.n\"
  803. else
  804. echo shar: Extracting \"cribbage.n\" \(10652 characters\)
  805. sed "s/^X//" >cribbage.n <<'END_OF_cribbage.n'
  806. X.\" Copyright (c) 1980 Regents of the University of California.
  807. X.\" All rights reserved.  The Berkeley software License Agreement
  808. X.\" specifies the terms and conditions for redistribution.
  809. X.\"
  810. X.\"    @(#)cribbage.n    5.1 (Berkeley) 5/30/85
  811. X.\"
  812. X.so macro
  813. X.na
  814. X.PH "CRIBBAGE"
  815. X.sp 2
  816. X.ce
  817. Xfrom
  818. X.sp
  819. X.ce
  820. X.ul
  821. XAccording to Hoyle
  822. X.sp 2
  823. X.PG
  824. XCribbage is believed to have been invented by Sir John Suckling (1609-1642).
  825. XProbably it is an elaboration of an older game, Noddy.  The original game was
  826. Xplayed with hands of five cards; the modern game gives each player six.  That
  827. Xis virtually the only change from Suckling's directions.
  828. X.HP "Players."
  829. XTwo.  There are variants for three and four players, described later.
  830. X.HP "Cards."
  831. XThe pack of 52.  The cards in each suit rank: K (high), Q, J, 10, 9, 8,
  832. X7, 6, 5, 4, 3, 2, A.  The
  833. X.ul
  834. Xcounting values
  835. Xare: K, Q, J, 10, each 10 (wherefore these are called
  836. X.ul
  837. Xtenth cards);
  838. Xace, 1; each other card, its index value.
  839. X.HP "Cribbage Board".
  840. XIndispensable to scoring (unless you have a computer!, ed.) is the device
  841. Xknown as the
  842. X.ul
  843. Xcribbage board.
  844. XThis is a rectangular panel, long and narrow, in which are
  845. Xfour rows of 30 holes each.  (See illustration.)  At one end, or in the center,
  846. Xare two or four additional holes, called
  847. X.ul
  848. Xgame holes.
  849. XThe board is placed between the two players, and each keeps his own score on
  850. Xthe two rows of holes nearest himself.  Each is supplied with two
  851. X.ul
  852. Xpegs.
  853. XBefore the first hand, the pegs are placed in the game holes.  On
  854. Xmaking his first score, the player advances one peg an appropriate number
  855. Xof holes (one per point) away from the
  856. X.ul
  857. Xgame end
  858. Xof the board.  The second score is recorded by placing the second peg an
  859. Xappropriate distance ahead of the first.  For each subsequent score, the
  860. Xrear peg is jumped ahead of the other, the distance between the two pegs
  861. Xalways showing the amount of this last score.
  862. X.PG
  863. XThe traditional mode of scoring is down (away from the game end) the
  864. Xouter row, and up the inner row.  "Once around" is a game of 61 points.
  865. X"Twice around" is a game of 121 points.
  866. X.HP "Preliminaries."
  867. XCards are drawn; the lower deals first.  If cards of equal rank are drawn,
  868. Xboth players draw again.  Dealer has the right to shuffle last.  Nondealer
  869. Xcuts, and must leave at least four cards in each packet.
  870. X.HP "Dealing."
  871. XEach player receives six cards, dealt one at a time face down, beginning
  872. Xwith the nondealer.  The turn to deal alternates.  The dealer has an
  873. Xadvantage.
  874. X.HP "Laying Away."
  875. XAfter seeing his hand, each player
  876. X.ul
  877. Xlays away
  878. Xtwo cards face down.  The four cards laid away, placed in one pile, form the
  879. X.ul
  880. Xcrib.
  881. XThe crib counts for the dealer.  Nondealer therefore tries to lay away
  882. X.ul
  883. Xbalking cards --
  884. Xcards that are least likely to create a score in the crib.
  885. X.HP "The Starter."
  886. XAfter both hands have laid away, nondealer lifts off a packet from the top
  887. Xof the
  888. X.ul
  889. Xstock
  890. X(the rest of the pack).  Again, each packet must contain at least four cards.
  891. XDealer turns up the top card of the lower packer, which is then placed on
  892. Xtop of the stock when the packets are reunited.  The card thus turned up is
  893. Xcalled
  894. X.ul
  895. X1 the starter.
  896. XIf it is a jack, dealer immediately pegs 2, called
  897. X.ul
  898. X2 for his heels.
  899. X.HP "The Play."
  900. XNondealer begins the play by laying a card from his hand face up on the
  901. Xtable, announcing its counting value.  Dealer then shows a card, announcing
  902. Xthe total count of the two cards.  Play continues in the same way, by
  903. Xalternate exposure of cards, each player announcing the new total count.
  904. XThe total may be carried only to 31, no further.  If a player adds a card
  905. Xthat brings the total exactly to 31, he pegs 2.  If a player is unable to
  906. Xplay another card without exceeding 31, he must say "Go," and his opponent
  907. Xpegs 1, but before doing so, opponent must lay down any additional cards he
  908. Xcan without exceeding 31.  If such additional cards bring the total to
  909. Xexactly 31, he pegs 2 instead of 1.
  910. X.PG
  911. XWhenever a
  912. X.ul
  913. Xgo 
  914. Xoccurs, the opponent of the player who played the last card must lead for a
  915. Xnew count starting at zero.  Playing the last card of all counts as a go.
  916. X(Since nondealer makes the opening lead, dealer is bound to peg at least
  917. X1 in play.)
  918. X.PG
  919. XBesides pegging for 31 and go, the player may also peg for certain
  920. Xcombinations made in play, as follows:
  921. X.sp 2
  922. X.ti +4
  923. X.ul
  924. XFifteen.
  925. X.IP
  926. XMaking the count total 15 pegs 2.
  927. X.EP
  928. X.sp 2
  929. X.ti +4
  930. X.ul
  931. XPair.
  932. X.IP
  933. XPlaying a card of same rank as that previously played pegs 2.  Playing
  934. Xa third card of the same rank makes
  935. X.ul
  936. Xpair royal
  937. Xand pegs 6.  Playing the fourth card of the same rank makes
  938. X.ul
  939. Xdouble pair royal
  940. Xand pegs 12.
  941. X.PG
  942. XThe tenth cards pair strictly by rank, a king with a king, a queen with a
  943. Xqueen, and so on.  (King and jack do not make a pair, although each has
  944. Xthe counting value 10.)
  945. X.EP
  946. X.sp 2
  947. X.ti +4
  948. X.ul
  949. XRun.
  950. X.IP
  951. XPlaying a card which, with the two or more played immediately previously,
  952. Xmakes a sequence of three or more cards, pegs 1 for each card in the
  953. X.ul
  954. Xrun.
  955. XRuns depend on rank alone; the suits do not matter.  Nor does the score
  956. Xfor run depend upon playing the cards in strict sequence, so long as
  957. Xthe three or more last cards played can be arranged in a run.
  958. X.ul
  959. XExample:
  960. X7, 6, 8 played in that order score 3 for run; 5, 2, 4, 3 played in that order
  961. Xscore 4 for run.
  962. X.EP
  963. X.PG
  964. XAny of the foregoing combinations count, whether the cards are played
  965. Xalternately or one player plays several times in succession in consequence
  966. Xof a go.  But a combination does not score if it is interrupted by a go.
  967. X.HP "Showing."
  968. XAfter the play, the hands are
  969. X.ul
  970. Xshown
  971. X(counted).  Nondealer shows first, then dealer's hand, then crib.
  972. XThe starter is deemed to belong to each hand, so that each hand includes
  973. Xfive cards.  Combinations of scoring value are as follows:
  974. X.sp 2
  975. X.ti +4
  976. X.ul
  977. XFifteen.
  978. X.IP
  979. XEach combinations of two or more cards that total fifteen scores 2.
  980. X.EP
  981. X.sp 2
  982. X.ti +4
  983. X.ul
  984. XPair.
  985. X.IP
  986. XEach pair of cards of the same rank scores 2.
  987. X.EP
  988. X.sp 2
  989. X.ti +4
  990. X.ul
  991. XRun.
  992. X.IP
  993. XEach combination of three or more cards in sequence scores 1 for each card
  994. Xin the run.
  995. X.EP
  996. X.sp 2
  997. X.ti +4
  998. X.ul
  999. XFlush.
  1000. X.IP
  1001. XFour cards of the same suit in hand score 4; four cards in hand or crib
  1002. Xof same suit as the starter score 5.  (No count for four-flush in crib.)
  1003. X.EP
  1004. X.sp 2
  1005. X.ti +4
  1006. X.ul
  1007. XHis Nobs.
  1008. X.IP
  1009. XJack of same suit as the starter, in hand or crib, scores 1.
  1010. X.EP
  1011. X.PG
  1012. XIt is important to note that every separate grouping of cards that makes
  1013. Xa fifteen, pair, or run counts separately.  Three of a kind,
  1014. X.ul
  1015. Xpair royal,
  1016. Xcounts 6 because three sets of pairs can be made; similarly, four of a
  1017. Xkind,
  1018. X.ul
  1019. Xdouble pair royal,
  1020. Xcontain six pairs and count 12.
  1021. X.PG
  1022. XThe highest possible hand is J, 5, 5, 5 with the starter the 5 of the same
  1023. Xsuit as the jack.  There are four fifteens by combining the jack with a
  1024. Xfive, four more by combinations of three fives (a total of 16 for fifteens);
  1025. Xthe double pair royal adds 12 for a total of 28; and
  1026. X.ul
  1027. Xhis nobs
  1028. Xadds 1 for a maximum score of 29.  (the score of 2 for
  1029. X.ul
  1030. Xhis heels
  1031. Xdoes not count in the total of the hand, since it is pegged before the play.)
  1032. X.PG
  1033. XA
  1034. X.ul
  1035. Xdouble run
  1036. Xis a run with one card duplicated, as 4-3-3-2.  Exclusive of fifteens, a
  1037. Xdouble run of three cards counts 8; of four cards, 10.  A
  1038. X.ul
  1039. Xtriple run
  1040. Xis a run of three with one card triplicated, as K-K-K-Q-J.  Exclusive of
  1041. Xfifteens, it counts 15.  A
  1042. X.ul
  1043. Xquadruple run
  1044. Xis a run of three with two different cards duplicated, as the example
  1045. X8-8-7-6-6 previously given.  Exclusive of fifteens, it counts 16.
  1046. X.PG
  1047. XNo hand can be constructed that counts 19, 25, 26 or 27.  A time-honored
  1048. Xway of showing a hand with not a single counting combination is to say
  1049. X"I have nineteen."
  1050. X.PG
  1051. XThe customary oder in showing is to count fifteens first, then runs, then
  1052. Xpairs, but there is no compulsion of law.
  1053. X.ul
  1054. XExample:
  1055. XA hand (with starter) of 9-6-5-4-4 will usually be counted "Fifteen 2,
  1056. Xfifteen 4, fifteen 6 and double run makes 14," or simply "Fifteen 6 and
  1057. X8 is 14."
  1058. X.HP "Muggins."
  1059. XThe hands and crib are counted aloud, and if a player claims a greater
  1060. Xtotal than is due him, his opponent may require correction.  In some
  1061. Xlocalities, if a player claims less than is due, his opponent may say
  1062. X"Muggins" and himself score the points overlooked.
  1063. X.HP "Scoring."
  1064. XThe usual
  1065. X.ul
  1066. Xgame
  1067. Xis 121, but it may be set at 61 by agreement.  Since the player wins
  1068. Xwho first returns to the game hole by going "twice around," the scores
  1069. Xmust be pegged strictly in order: his heels, pegging in play, non-dealer's
  1070. Xhand, dealer's hand, crib.  Thus, if nondealer goes out on showing his
  1071. Xhand, he wins, even though dealer might have gone out with a greater
  1072. Xtotal if allowed to count his hand and crib.
  1073. X.PG
  1074. XWhen the game of 121 is played for a stake, a player wins a single game
  1075. Xif the loser makes 61 points or more.  If the loser fails to reach
  1076. X61, he is
  1077. X.ul
  1078. Xlurched,
  1079. Xand the other wins a double game.
  1080. X.HP "Irregularities."
  1081. X.ul
  1082. XMisdeal.
  1083. XThere must be a new deal by the same dealer if a card is found faced in the
  1084. Xpack, if a card is exposed in dealing, or if the pack be found imperfect.
  1085. X.PG
  1086. X.ul
  1087. XWrong Number of Cards.
  1088. XIf one hand (not crib) is found to have the wrong number of cards after
  1089. Xlaying away for the crib, the other hand and crib being correct, the
  1090. Xopponent may either demand a new deal or may peg 2 and rectify the
  1091. Xhand.  If the crib is incorrect, both hands being correct, nondealer
  1092. Xpegs 2 and the crib is corrected.
  1093. X.HP "Error in Pegging."
  1094. XIf a player places a peg short of the amount to which he is entitled, he
  1095. Xmay not correct his error after he has played the next card or after the
  1096. Xcut for the next deal.  If he pegs more than his announced score,
  1097. Xthe error must be corrected on demand at any time before the cut for the
  1098. Xnext deal and his opponent pegs 2.
  1099. X.HP "Strategy."
  1100. XThe best balking cards are kings and aces, because they have the least
  1101. Xchance of producing sequences.  Tenth cards are generally good, provided
  1102. Xthat the two cards laid away are not too
  1103. X.ul
  1104. Xnear
  1105. X(likely to make a sequence).  When nothing better offers, give two
  1106. X.ul
  1107. Xwide
  1108. Xcards -- at least three apart in rank.
  1109. X.PG
  1110. XProverbially the safest lead is a 4.  The next card cannot make a 15.
  1111. XLower cards are also safe from this point of view, but are better
  1112. Xtreasured for go and 31.  The most dangerous leads are 7 and 8, but
  1113. Xmay be made to trap the opponent when they are backed with other
  1114. Xclose cards.  Generally speaking, play
  1115. X.ul
  1116. Xon
  1117. X(toward a sequence) when you have close cards and
  1118. X.ul
  1119. Xoff
  1120. Xwhen you do not.  However, the state of the score is a consideration.
  1121. XIf far behind, play on when there is any chance of building a score
  1122. Xfor yourself; if well ahead, balk your opponent by playing off unless
  1123. Xyou will surely peg as much as he by playing on.
  1124. END_OF_cribbage.n
  1125. if test 10652 -ne `wc -c <cribbage.n`; then
  1126.     echo shar: \"cribbage.n\" unpacked with wrong size!
  1127. fi
  1128. # end of overwriting check
  1129. fi
  1130. if test -f cribcur.h -a "${1}" != "-c" ; then 
  1131.   echo shar: Will not over-write existing file \"cribcur.h\"
  1132. else
  1133. echo shar: Extracting \"cribcur.h\" \(1451 characters\)
  1134. sed "s/^X//" >cribcur.h <<'END_OF_cribcur.h'
  1135. X/*
  1136. X * Copyright (c) 1980 Regents of the University of California.
  1137. X * All rights reserved.
  1138. X *
  1139. X * Redistribution and use in source and binary forms are permitted
  1140. X * provided that this notice is preserved and that due credit is given
  1141. X * to the University of California at Berkeley. The name of the University
  1142. X * may not be used to endorse or promote products derived from this
  1143. X * software without specific prior written permission. This software
  1144. X * is provided ``as is'' without express or implied warranty.
  1145. X *
  1146. X *    @(#)cribcur.h    5.2 (Berkeley) 3/10/88
  1147. X */
  1148. X
  1149. X# define    PLAY_Y        15    /* size of player's hand window */
  1150. X# define    PLAY_X        12
  1151. X# define    TABLE_Y        21    /* size of table window */
  1152. X# define    TABLE_X        14
  1153. X# define    COMP_Y        15    /* size of computer's hand window */
  1154. X# define    COMP_X        12
  1155. X# define    Y_SCORE_SZ    9    /* Y size of score board */
  1156. X# define    X_SCORE_SZ    41    /* X size of score board */
  1157. X# define    SCORE_Y        0    /* starting position of scoring board */
  1158. X# define    SCORE_X         (PLAY_X + TABLE_X + COMP_X)
  1159. X# define    CRIB_Y        17    /* position of crib (cut card) */
  1160. X# define    CRIB_X        (PLAY_X + TABLE_X)
  1161. X# define    MSG_Y        (LINES - (Y_SCORE_SZ + 1))
  1162. X# define    MSG_X        (COLS - SCORE_X - 1)
  1163. X# define    Y_MSG_START    (Y_SCORE_SZ + 1)
  1164. X
  1165. X# define    PEG    '*'    /* what a peg looks like on the board */
  1166. X
  1167. Xextern    WINDOW        *Compwin;        /* computer's hand window */
  1168. Xextern    WINDOW        *Msgwin;        /* message window */
  1169. Xextern    WINDOW        *Playwin;        /* player's hand window */
  1170. Xextern    WINDOW        *Tablewin;        /* table window */
  1171. END_OF_cribcur.h
  1172. if test 1451 -ne `wc -c <cribcur.h`; then
  1173.     echo shar: \"cribcur.h\" unpacked with wrong size!
  1174. fi
  1175. # end of overwriting check
  1176. fi
  1177. if test -f io.c -a "${1}" != "-c" ; then 
  1178.   echo shar: Will not over-write existing file \"io.c\"
  1179. else
  1180. echo shar: Extracting \"io.c\" \(11117 characters\)
  1181. sed "s/^X//" >io.c <<'END_OF_io.c'
  1182. X/*
  1183. X * Copyright (c) 1980 Regents of the University of California.
  1184. X * All rights reserved.
  1185. X *
  1186. X * Redistribution and use in source and binary forms are permitted
  1187. X * provided that this notice is preserved and that due credit is given
  1188. X * to the University of California at Berkeley. The name of the University
  1189. X * may not be used to endorse or promote products derived from this
  1190. X * software without specific prior written permission. This software
  1191. X * is provided ``as is'' without express or implied warranty.
  1192. X */
  1193. X
  1194. X#ifndef lint
  1195. Xstatic char sccsid[] = "@(#)io.c    5.3 (Berkeley) 3/10/88";
  1196. X#endif /* not lint */
  1197. X
  1198. X# include    <curses.h>
  1199. X# include    <ctype.h>
  1200. X# include    <signal.h>
  1201. X# include    "deck.h"
  1202. X# include    "cribbage.h"
  1203. X# include    "cribcur.h"
  1204. X
  1205. X# define    LINESIZE        128
  1206. X
  1207. X# ifdef CTRL
  1208. X# undef CTRL
  1209. X# endif
  1210. X# define    CTRL(X)            ('X' - 'A' + 1)
  1211. X
  1212. X# ifdef    notdef                /* defined in curses.h */
  1213. X#    define    erasechar()    _tty.sg_erase
  1214. X#    define    killchar()    _tty.sg_kill
  1215. X# endif
  1216. X
  1217. Xchar        linebuf[ LINESIZE ];
  1218. X
  1219. Xchar        *rankname[ RANKS ]    = { "ACE", "TWO", "THREE", "FOUR",
  1220. X                        "FIVE", "SIX", "SEVEN", "EIGHT",
  1221. X                        "NINE", "TEN", "JACK", "QUEEN",
  1222. X                        "KING" };
  1223. X
  1224. Xchar            *rankchar[ RANKS ]      = { "A", "2", "3", "4", "5", "6", "7",
  1225. X                        "8", "9", "T", "J", "Q", "K" };
  1226. X
  1227. Xchar            *suitname[ SUITS ]      = { "SPADES", "HEARTS", "DIAMONDS",
  1228. X                        "CLUBS" };
  1229. X
  1230. Xchar            *suitchar[ SUITS ]      = { "S", "H", "D", "C" };
  1231. X
  1232. X
  1233. X
  1234. X/*
  1235. X * msgcard:
  1236. X *    Call msgcrd in one of two forms
  1237. X */
  1238. Xmsgcard(c, brief)
  1239. XCARD        c;
  1240. XBOOLEAN        brief;
  1241. X{
  1242. X    if (brief)
  1243. X        return msgcrd(c, TRUE, (char *) NULL, TRUE);
  1244. X    else
  1245. X        return msgcrd(c, FALSE, " of ", FALSE);
  1246. X}
  1247. X
  1248. X
  1249. X
  1250. X/*
  1251. X * msgcrd:
  1252. X *    Print the value of a card in ascii
  1253. X */
  1254. Xmsgcrd(c, brfrank, mid, brfsuit)
  1255. XCARD        c;
  1256. Xchar        *mid;
  1257. XBOOLEAN        brfrank,  brfsuit;
  1258. X{
  1259. X    if (c.rank == EMPTY || c.suit == EMPTY)
  1260. X        return FALSE;
  1261. X    if (brfrank)
  1262. X        addmsg("%1.1s", rankchar[c.rank]);
  1263. X    else
  1264. X        addmsg(rankname[c.rank]);
  1265. X    if (mid != NULL)
  1266. X        addmsg(mid);
  1267. X    if (brfsuit)
  1268. X        addmsg("%1.1s", suitchar[c.suit]);
  1269. X    else
  1270. X        addmsg(suitname[c.suit]);
  1271. X    return TRUE;
  1272. X}
  1273. X
  1274. X/*
  1275. X * printcard:
  1276. X *    Print out a card.
  1277. X */
  1278. Xprintcard(win, cardno, c, blank)
  1279. XWINDOW        *win;
  1280. Xint        cardno;
  1281. XCARD        c;
  1282. XBOOLEAN        blank;
  1283. X{
  1284. X    prcard(win, cardno * 2, cardno, c, blank);
  1285. X}
  1286. X
  1287. X/*
  1288. X * prcard:
  1289. X *    Print out a card on the window at the specified location
  1290. X */
  1291. Xprcard(win, y, x, c, blank)
  1292. XWINDOW        *win;
  1293. Xint        y, x;
  1294. XCARD        c;
  1295. XBOOLEAN        blank;
  1296. X{
  1297. X    if (c.rank == EMPTY)
  1298. X        return;
  1299. X    mvwaddstr(win, y + 0, x, "+-----+");
  1300. X    mvwaddstr(win, y + 1, x, "|     |");
  1301. X    mvwaddstr(win, y + 2, x, "|     |");
  1302. X    mvwaddstr(win, y + 3, x, "|     |");
  1303. X    mvwaddstr(win, y + 4, x, "+-----+");
  1304. X    if (!blank) {
  1305. X        mvwaddch(win, y + 1, x + 1, rankchar[c.rank][0]);
  1306. X        waddch(win, suitchar[c.suit][0]);
  1307. X        mvwaddch(win, y + 3, x + 4, rankchar[c.rank][0]);
  1308. X        waddch(win, suitchar[c.suit][0]);
  1309. X    }
  1310. X}
  1311. X
  1312. X/*
  1313. X * prhand:
  1314. X *    Print a hand of n cards
  1315. X */
  1316. Xprhand(h, n, win, blank)
  1317. XCARD        h[];
  1318. Xint        n;
  1319. XWINDOW        *win;
  1320. XBOOLEAN        blank;
  1321. X{
  1322. X    register int    i;
  1323. X
  1324. X    werase(win);
  1325. X    for (i = 0; i < n; i++)
  1326. X        printcard(win, i, *h++, blank);
  1327. X    wrefresh(win);
  1328. X}
  1329. X
  1330. X
  1331. X
  1332. X/*
  1333. X * infrom:
  1334. X *    reads a card, supposedly in hand, accepting unambigous brief
  1335. X *    input, returns the index of the card found...
  1336. X */
  1337. Xinfrom(hand, n, prompt)
  1338. XCARD        hand[];
  1339. Xint        n;
  1340. Xchar        *prompt;
  1341. X{
  1342. X    register int           i, j;
  1343. X    CARD                    crd;
  1344. X
  1345. X    if (n < 1) {
  1346. X        printf("\nINFROM: %d = n < 1!!\n", n);
  1347. X        exit(74);
  1348. X    }
  1349. X    for (;;) {
  1350. X        msg(prompt);
  1351. X        if (incard(&crd)) {            /* if card is full card */
  1352. X        if (!isone(crd, hand, n))
  1353. X            msg("That's not in your hand");
  1354. X        else {
  1355. X            for (i = 0; i < n; i++)
  1356. X            if (hand[i].rank == crd.rank &&
  1357. X                hand[i].suit == crd.suit)
  1358. X                break;
  1359. X            if (i >= n) {
  1360. X            printf("\nINFROM: isone or something messed up\n");
  1361. X            exit(77);
  1362. X            }
  1363. X            return i;
  1364. X        }
  1365. X        }
  1366. X        else                /* if not full card... */
  1367. X        if (crd.rank != EMPTY) {
  1368. X            for (i = 0; i < n; i++)
  1369. X            if (hand[i].rank == crd.rank)
  1370. X                break;
  1371. X            if (i >= n)
  1372. X            msg("No such rank in your hand");
  1373. X            else {
  1374. X            for (j = i + 1; j < n; j++)
  1375. X                if (hand[j].rank == crd.rank)
  1376. X                break;
  1377. X            if (j < n)
  1378. X                msg("Ambiguous rank");
  1379. X            else
  1380. X                return i;
  1381. X            }
  1382. X        }
  1383. X        else
  1384. X            msg("Sorry, I missed that");
  1385. X    }
  1386. X    /* NOTREACHED */
  1387. X}
  1388. X
  1389. X
  1390. X
  1391. X/*
  1392. X * incard:
  1393. X *    Inputs a card in any format.  It reads a line ending with a CR
  1394. X *    and then parses it.
  1395. X */
  1396. Xincard(crd)
  1397. XCARD        *crd;
  1398. X{
  1399. X    char        *getline();
  1400. X    register int    i;
  1401. X    int        rnk, sut;
  1402. X    char        *line, *p, *p1;
  1403. X    BOOLEAN        retval;
  1404. X
  1405. X    retval = FALSE;
  1406. X    rnk = sut = EMPTY;
  1407. X    if (!(line = getline()))
  1408. X        goto gotit;
  1409. X    p = p1 = line;
  1410. X    while(  *p1 != ' '  &&  *p1 != NULL  )  ++p1;
  1411. X    *p1++ = NULL;
  1412. X    if(  *p == NULL  )  goto  gotit;
  1413. X            /* IMPORTANT: no real card has 2 char first name */
  1414. X    if(  strlen(p) == 2  )  {               /* check for short form */
  1415. X        rnk = EMPTY;
  1416. X        for( i = 0; i < RANKS; i++ )  {
  1417. X        if(  *p == *rankchar[i]  )  {
  1418. X            rnk = i;
  1419. X            break;
  1420. X        }
  1421. X        }
  1422. X        if(  rnk == EMPTY  )  goto  gotit;     /* it's nothing... */
  1423. X        ++p;                                /* advance to next char */
  1424. X        sut = EMPTY;
  1425. X        for( i = 0; i < SUITS; i++ )  {
  1426. X        if(  *p == *suitchar[i]  )  {
  1427. X            sut = i;
  1428. X            break;
  1429. X        }
  1430. X        }
  1431. X        if(  sut != EMPTY  )  retval = TRUE;
  1432. X        goto  gotit;
  1433. X    }
  1434. X    rnk = EMPTY;
  1435. X    for( i = 0; i < RANKS; i++ )  {
  1436. X        if(  !strcmp( p, rankname[i] )  ||  !strcmp( p, rankchar[i] )  )  {
  1437. X        rnk = i;
  1438. X        break;
  1439. X        }
  1440. X    }
  1441. X    if(  rnk == EMPTY  )  goto  gotit;
  1442. X    p = p1;
  1443. X    while(  *p1 != ' '  &&  *p1 != NULL  )  ++p1;
  1444. X    *p1++ = NULL;
  1445. X    if(  *p == NULL  )  goto  gotit;
  1446. X    if(  !strcmp( "OF", p )  )  {
  1447. X        p = p1;
  1448. X        while(  *p1 != ' '  &&  *p1 != NULL  )  ++p1;
  1449. X        *p1++ = NULL;
  1450. X        if(  *p == NULL  )  goto  gotit;
  1451. X    }
  1452. X    sut = EMPTY;
  1453. X    for( i = 0; i < SUITS; i++ )  {
  1454. X        if(  !strcmp( p, suitname[i] )  ||  !strcmp( p, suitchar[i] )  )  {
  1455. X        sut = i;
  1456. X        break;
  1457. X        }
  1458. X    }
  1459. X    if(  sut != EMPTY  )  retval = TRUE;
  1460. Xgotit:
  1461. X    (*crd).rank = rnk;
  1462. X    (*crd).suit = sut;
  1463. X    return( retval );
  1464. X}
  1465. X
  1466. X
  1467. X
  1468. X/*
  1469. X * getuchar:
  1470. X *    Reads and converts to upper case
  1471. X */
  1472. Xgetuchar()
  1473. X{
  1474. X    register int        c;
  1475. X
  1476. X    c = readchar();
  1477. X    if (islower(c))
  1478. X        c = toupper(c);
  1479. X    waddch(Msgwin, c);
  1480. X    return c;
  1481. X}
  1482. X
  1483. X/*
  1484. X * number:
  1485. X *    Reads in a decimal number and makes sure it is between "lo" and
  1486. X *    "hi" inclusive.
  1487. X */
  1488. Xnumber(lo, hi, prompt)
  1489. Xint        lo, hi;
  1490. Xchar        *prompt;
  1491. X{
  1492. X    char            *getline();
  1493. X    register char        *p;
  1494. X    register int        sum;
  1495. X
  1496. X    sum = 0;
  1497. X    for (;;) {
  1498. X        msg(prompt);
  1499. X        if(!(p = getline()) || *p == NULL) {
  1500. X        msg(quiet ? "Not a number" : "That doesn't look like a number");
  1501. X        continue;
  1502. X        }
  1503. X        sum = 0;
  1504. X
  1505. X        if (!isdigit(*p))
  1506. X        sum = lo - 1;
  1507. X        else
  1508. X        while (isdigit(*p)) {
  1509. X            sum = 10 * sum + (*p - '0');
  1510. X            ++p;
  1511. X        }
  1512. X
  1513. X        if (*p != ' ' && *p != '\t' && *p != NULL)
  1514. X        sum = lo - 1;
  1515. X        if (sum >= lo && sum <= hi)
  1516. X        return sum;
  1517. X        if (sum == lo - 1)
  1518. X        msg("that doesn't look like a number, try again --> ");
  1519. X        else
  1520. X        msg("%d is not between %d and %d inclusive, try again --> ",
  1521. X                                sum, lo, hi);
  1522. X    }
  1523. X}
  1524. X
  1525. X/*
  1526. X * msg:
  1527. X *    Display a message at the top of the screen.
  1528. X */
  1529. Xchar        Msgbuf[BUFSIZ] = { '\0' };
  1530. X
  1531. Xint        Mpos = 0;
  1532. X
  1533. Xstatic int    Newpos = 0;
  1534. X
  1535. X/* VARARGS1 */
  1536. Xmsg(fmt, args)
  1537. Xchar    *fmt;
  1538. Xint    args;
  1539. X{
  1540. X    doadd(fmt, &args);
  1541. X    endmsg();
  1542. X}
  1543. X
  1544. X/*
  1545. X * addmsg:
  1546. X *    Add things to the current message
  1547. X */
  1548. X/* VARARGS1 */
  1549. Xaddmsg(fmt, args)
  1550. Xchar    *fmt;
  1551. Xint    args;
  1552. X{
  1553. X    doadd(fmt, &args);
  1554. X}
  1555. X
  1556. X/*
  1557. X * endmsg:
  1558. X *    Display a new msg.
  1559. X */
  1560. X
  1561. Xint    Lineno = 0;
  1562. X
  1563. Xendmsg()
  1564. X{
  1565. X    register int    len;
  1566. X    register char    *mp, *omp;
  1567. X    static int        lastline = 0;
  1568. X
  1569. X    /*
  1570. X     * All messages should start with uppercase
  1571. X     */
  1572. X    mvaddch(lastline + Y_MSG_START, SCORE_X, ' ');
  1573. X    if (islower(Msgbuf[0]) && Msgbuf[1] != ')')
  1574. X    Msgbuf[0] = toupper(Msgbuf[0]);
  1575. X    mp = Msgbuf;
  1576. X    len = strlen(mp);
  1577. X    if (len / MSG_X + Lineno >= MSG_Y) {
  1578. X    while (Lineno < MSG_Y) {
  1579. X        wmove(Msgwin, Lineno++, 0);
  1580. X        wclrtoeol(Msgwin);
  1581. X    }
  1582. X    Lineno = 0;
  1583. X    }
  1584. X    mvaddch(Lineno + Y_MSG_START, SCORE_X, '*');
  1585. X    lastline = Lineno;
  1586. X    do {
  1587. X    mvwaddstr(Msgwin, Lineno, 0, mp);
  1588. X    if ((len = strlen(mp)) > MSG_X) {
  1589. X        omp = mp;
  1590. X        for (mp = &mp[MSG_X-1]; *mp != ' '; mp--)
  1591. X            continue;
  1592. X        while (*mp == ' ')
  1593. X        mp--;
  1594. X        mp++;
  1595. X        wmove(Msgwin, Lineno, mp - omp);
  1596. X        wclrtoeol(Msgwin);
  1597. X    }
  1598. X    if (++Lineno >= MSG_Y)
  1599. X        Lineno = 0;
  1600. X    } while (len > MSG_X);
  1601. X    wclrtoeol(Msgwin);
  1602. X    Mpos = len;
  1603. X    Newpos = 0;
  1604. X    wrefresh(Msgwin);
  1605. X    refresh();
  1606. X    wrefresh(Msgwin);
  1607. X}
  1608. X
  1609. X/*
  1610. X * doadd:
  1611. X *    Perform an add onto the message buffer
  1612. X */
  1613. Xdoadd(fmt, args)
  1614. Xchar    *fmt;
  1615. Xint    *args;
  1616. X{
  1617. X    static FILE    junk;
  1618. X
  1619. X    /*
  1620. X     * Do the printf into Msgbuf
  1621. X     */
  1622. X    junk._flag = _IOWRT + _IOSTRG;
  1623. X    junk._ptr = &Msgbuf[Newpos];
  1624. X    junk._cnt = 32767;
  1625. X    _doprnt(fmt, args, &junk);
  1626. X    putc('\0', &junk);
  1627. X    Newpos = strlen(Msgbuf);
  1628. X}
  1629. X
  1630. X/*
  1631. X * do_wait:
  1632. X *    Wait for the user to type ' ' before doing anything else
  1633. X */
  1634. Xdo_wait()
  1635. X{
  1636. X    register int line;
  1637. X    static char prompt[] = { '-', '-', 'M', 'o', 'r', 'e', '-', '-', '\0' };
  1638. X
  1639. X    if (Mpos + sizeof prompt < MSG_X)
  1640. X    wmove(Msgwin, Lineno > 0 ? Lineno - 1 : MSG_Y - 1, Mpos);
  1641. X    else {
  1642. X    mvwaddch(Msgwin, Lineno, 0, ' ');
  1643. X    wclrtoeol(Msgwin);
  1644. X    if (++Lineno >= MSG_Y)
  1645. X        Lineno = 0;
  1646. X    }
  1647. X    waddstr(Msgwin, prompt);
  1648. X    wrefresh(Msgwin);
  1649. X    wait_for(' ');
  1650. X}
  1651. X
  1652. X/*
  1653. X * wait_for
  1654. X *    Sit around until the guy types the right key
  1655. X */
  1656. Xwait_for(ch)
  1657. Xregister char    ch;
  1658. X{
  1659. X    register char    c;
  1660. X
  1661. X    if (ch == '\n')
  1662. X    while ((c = readchar()) != '\n')
  1663. X        continue;
  1664. X    else
  1665. X    while (readchar() != ch)
  1666. X        continue;
  1667. X}
  1668. X
  1669. X/*
  1670. X * readchar:
  1671. X *    Reads and returns a character, checking for gross input errors
  1672. X */
  1673. Xreadchar()
  1674. X{
  1675. X    register int    cnt, y, x;
  1676. X    auto char        c;
  1677. X
  1678. Xover:
  1679. X    cnt = 0;
  1680. X    while (read(0, &c, 1) <= 0)
  1681. X    if (cnt++ > 100)    /* if we are getting infinite EOFs */
  1682. X        bye();        /* quit the game */
  1683. X    if (c == CTRL(L)) {
  1684. X    wrefresh(curscr);
  1685. X    goto over;
  1686. X    }
  1687. X    if (c == '\r')
  1688. X    return '\n';
  1689. X    else
  1690. X    return c;
  1691. X}
  1692. X
  1693. X/*
  1694. X * getline:
  1695. X *      Reads the next line up to '\n' or EOF.  Multiple spaces are
  1696. X *    compressed to one space; a space is inserted before a ','
  1697. X */
  1698. Xchar *
  1699. Xgetline()
  1700. X{
  1701. X    register char    *sp;
  1702. X    register int    c, oy, ox;
  1703. X    register WINDOW    *oscr;
  1704. X
  1705. X    oscr = stdscr;
  1706. X    stdscr = Msgwin;
  1707. X    getyx(stdscr, oy, ox);
  1708. X    refresh();
  1709. X    /*
  1710. X     * loop reading in the string, and put it in a temporary buffer
  1711. X     */
  1712. X    for (sp = linebuf; (c = readchar()) != '\n'; clrtoeol(), refresh()) {
  1713. X    if (c == -1)
  1714. X        continue;
  1715. X    else if (c == erasechar()) {    /* process erase character */
  1716. X        if (sp > linebuf) {
  1717. X        register int i;
  1718. X
  1719. X        sp--;
  1720. X        for (i = strlen(unctrl(*sp)); i; i--)
  1721. X            addch('\b');
  1722. X        }
  1723. X        continue;
  1724. X    }
  1725. X    else if (c == killchar()) {    /* process kill character */
  1726. X        sp = linebuf;
  1727. X        move(oy, ox);
  1728. X        continue;
  1729. X    }
  1730. X    else if (sp == linebuf && c == ' ')
  1731. X        continue;
  1732. X    if (sp >= &linebuf[LINESIZE-1] || !(isprint(c) || c == ' '))
  1733. X        putchar(CTRL(G));
  1734. X    else {
  1735. X        if (islower(c))
  1736. X        c = toupper(c);
  1737. X        *sp++ = c;
  1738. X        addstr(unctrl(c));
  1739. X        Mpos++;
  1740. X    }
  1741. X    }
  1742. X    *sp = '\0';
  1743. X    stdscr = oscr;
  1744. X    return linebuf;
  1745. X}
  1746. X
  1747. X/*
  1748. X * bye:
  1749. X *    Leave the program, cleaning things up as we go.
  1750. X */
  1751. Xbye()
  1752. X{
  1753. X    signal(SIGINT, SIG_IGN);
  1754. X    mvcur(0, COLS - 1, LINES - 1, 0);
  1755. X    fflush(stdout);
  1756. X    endwin();
  1757. X    putchar('\n');
  1758. X    exit(1);
  1759. X}
  1760. END_OF_io.c
  1761. if test 11117 -ne `wc -c <io.c`; then
  1762.     echo shar: \"io.c\" unpacked with wrong size!
  1763. fi
  1764. # end of overwriting check
  1765. fi
  1766. if test -f score.c -a "${1}" != "-c" ; then 
  1767.   echo shar: Will not over-write existing file \"score.c\"
  1768. else
  1769. echo shar: Extracting \"score.c\" \(9414 characters\)
  1770. sed "s/^X//" >score.c <<'END_OF_score.c'
  1771. X/*
  1772. X * Copyright (c) 1980 Regents of the University of California.
  1773. X * All rights reserved.
  1774. X *
  1775. X * Redistribution and use in source and binary forms are permitted
  1776. X * provided that this notice is preserved and that due credit is given
  1777. X * to the University of California at Berkeley. The name of the University
  1778. X * may not be used to endorse or promote products derived from this
  1779. X * software without specific prior written permission. This software
  1780. X * is provided ``as is'' without express or implied warranty.
  1781. X */
  1782. X
  1783. X#ifndef lint
  1784. Xstatic char sccsid[] = "@(#)score.c    5.3 (Berkeley) 3/10/88";
  1785. X#endif /* not lint */
  1786. X
  1787. X#include    <stdio.h>
  1788. X#include    "deck.h"
  1789. X#include    "cribbage.h"
  1790. X
  1791. X
  1792. X/*
  1793. X * the following arrays give the sum of the scores of the (50 2)*48 = 58800
  1794. X * hands obtainable for the crib given the two cards whose ranks index the
  1795. X * array.  the two arrays are for the case where the suits are equal and
  1796. X * not equal respectively
  1797. X */
  1798. X
  1799. Xlong        crbescr[ 169 ]        = {
  1800. X    -10000, 271827, 278883, 332319, 347769, 261129, 250653, 253203, 248259,
  1801. X    243435, 256275, 237435, 231051, -10000, -10000, 412815, 295707, 349497,
  1802. X    267519, 262521, 259695, 254019, 250047, 262887, 244047, 237663, -10000,
  1803. X    -10000, -10000, 333987, 388629, 262017, 266787, 262971, 252729, 254475,
  1804. X    267315, 248475, 242091, -10000, -10000, -10000, -10000, 422097, 302787,
  1805. X    256437, 263751, 257883, 254271, 267111, 248271, 241887, -10000, -10000,
  1806. X    -10000, -10000, -10000, 427677, 387837, 349173, 347985, 423861, 436701,
  1807. X    417861, 411477, -10000, -10000, -10000, -10000, -10000, -10000, 336387,
  1808. X    298851, 338667, 236487, 249327, 230487, 224103, -10000, -10000, -10000,
  1809. X    -10000, -10000, -10000, -10000, 408483, 266691, 229803, 246195, 227355,
  1810. X    220971, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
  1811. X    300675, 263787, 241695, 226407, 220023, -10000, -10000, -10000, -10000,
  1812. X    -10000, -10000, -10000, -10000, -10000, 295635, 273543, 219771, 216939,
  1813. X    -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
  1814. X    -10000, 306519, 252747, 211431, -10000, -10000, -10000, -10000, -10000,
  1815. X    -10000, -10000, -10000, -10000, -10000, -10000, 304287, 262971, -10000,
  1816. X    -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
  1817. X    -10000, -10000, 244131, -10000, -10000, -10000, -10000, -10000, -10000,
  1818. X    -10000, -10000, -10000, -10000, -10000, -10000, -10000  };
  1819. X
  1820. Xlong        crbnescr[ 169 ]        = {
  1821. X    325272, 260772, 267828, 321264, 336714, 250074, 239598, 242148, 237204,
  1822. X    232380, 246348, 226380, 219996, -10000, 342528, 401760, 284652, 338442,
  1823. X    256464, 251466, 248640, 242964, 238992, 252960, 232992, 226608, -10000,
  1824. X    -10000, 362280, 322932, 377574, 250962, 255732, 251916, 241674, 243420,
  1825. X    257388, 237420, 231036, -10000, -10000, -10000, 360768, 411042, 291732,
  1826. X    245382, 252696, 246828, 243216, 257184, 237216, 230832, -10000, -10000,
  1827. X    -10000, -10000, 528768, 416622, 376782, 338118, 336930, 412806, 426774,
  1828. X    406806, 400422, -10000, -10000, -10000, -10000, -10000, 369864, 325332,
  1829. X    287796, 327612, 225432, 239400, 219432, 213048, -10000, -10000, -10000,
  1830. X    -10000, -10000, -10000, 359160, 397428, 255636, 218748, 236268, 216300,
  1831. X    209916, -10000, -10000, -10000, -10000, -10000, -10000, -10000, 331320,
  1832. X    289620, 252732, 231768, 215352, 208968, -10000, -10000, -10000, -10000,
  1833. X    -10000, -10000, -10000, -10000, 325152, 284580, 263616, 208716, 205884,
  1834. X    -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
  1835. X    321240, 296592, 241692, 200376, -10000, -10000, -10000, -10000, -10000,
  1836. X    -10000, -10000, -10000, -10000, -10000, 348600, 294360, 253044, -10000,
  1837. X    -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
  1838. X    -10000, 308664, 233076, -10000, -10000, -10000, -10000, -10000, -10000,
  1839. X    -10000, -10000, -10000, -10000, -10000, -10000, 295896  };
  1840. X
  1841. X
  1842. Xstatic  int        ichoose2[ 5 ]        = { 0, 0, 2, 6, 12 };
  1843. Xstatic  int        pairpoints, runpoints;    /* globals from pairuns */
  1844. X
  1845. X
  1846. X/*
  1847. X * scorehand:
  1848. X *    Score the given hand of n cards and the starter card.
  1849. X *    n must be <= 4
  1850. X */
  1851. Xscorehand(hand, starter, n, crb, do_explain)
  1852. Xregister CARD        hand[];
  1853. XCARD            starter;
  1854. Xint            n;
  1855. XBOOLEAN            crb;        /* true if scoring crib */
  1856. XBOOLEAN            do_explain;    /* true if must explain this hand */
  1857. X{
  1858. X    CARD            h[(CINHAND + 1)];
  1859. X    register int        i, k;
  1860. X    register int        score;
  1861. X    register BOOLEAN    flag;
  1862. X    char            buf[32];
  1863. X
  1864. X    expl[0] = NULL;        /* initialize explanation */
  1865. X    score = 0;
  1866. X    flag = TRUE;
  1867. X    k = hand[0].suit;
  1868. X    for (i = 0; i < n; i++) {            /* check for flush */
  1869. X        flag = (flag && (hand[i].suit == k));
  1870. X        if (hand[i].rank == JACK)            /* check for his nibs */
  1871. X        if (hand[i].suit == starter.suit) {
  1872. X            score++;
  1873. X            if (do_explain)
  1874. X            strcat(expl, "His Nobs");
  1875. X        }
  1876. X        h[i] = hand[i];
  1877. X    }
  1878. X
  1879. X    if (flag && n >= CINHAND) {
  1880. X        if (do_explain && expl[0] != NULL)
  1881. X        strcat(expl, ", ");
  1882. X        if (starter.suit == k) {
  1883. X        score += 5;
  1884. X        if (do_explain)
  1885. X            strcat(expl, "Five-flush");
  1886. X        }
  1887. X        else if (!crb) {
  1888. X        score += 4;
  1889. X        if (do_explain && expl[0] != NULL)
  1890. X            strcat(expl, ", Four-flush");
  1891. X        else
  1892. X            strcpy(expl, "Four-flush");
  1893. X        }
  1894. X    }
  1895. X
  1896. X    if (do_explain && expl[0] != NULL)
  1897. X        strcat(expl, ", ");
  1898. X    h[n] = starter;
  1899. X    sorthand(h, n + 1);            /* sort by rank */
  1900. X    i = 2 * fifteens(h, n + 1);
  1901. X    score += i;
  1902. X    if (do_explain)
  1903. X        if (i > 0) {
  1904. X        (void)sprintf(buf, "%d points in fifteens", i);
  1905. X        strcat(expl, buf);
  1906. X        }
  1907. X        else
  1908. X        strcat(expl, "No fifteens");
  1909. X    i = pairuns(h, n + 1);
  1910. X    score += i;
  1911. X    if (do_explain)
  1912. X        if (i > 0) {
  1913. X        (void)sprintf(buf, ", %d points in pairs, %d in runs",
  1914. X            pairpoints, runpoints);
  1915. X        strcat(expl, buf);
  1916. X        }
  1917. X        else
  1918. X        strcat(expl, ", No pairs/runs");
  1919. X    return score;
  1920. X}
  1921. X
  1922. X/*
  1923. X * fifteens:
  1924. X *    Return number of fifteens in hand of n cards
  1925. X */
  1926. Xfifteens(hand, n)
  1927. Xregister CARD        hand[];
  1928. Xint            n;
  1929. X{
  1930. X    register int        *sp, *np;
  1931. X    register int        i;
  1932. X    register CARD        *endp;
  1933. X    static int        sums[15], nsums[15];
  1934. X
  1935. X    np = nsums;
  1936. X    sp = sums;
  1937. X    i = 16;
  1938. X    while (--i) {
  1939. X        *np++ = 0;
  1940. X        *sp++ = 0;
  1941. X    }
  1942. X    for (endp = &hand[n]; hand < endp; hand++) {
  1943. X        i = hand->rank + 1;
  1944. X        if (i > 10)
  1945. X        i = 10;
  1946. X        np = &nsums[i];
  1947. X        np[-1]++;            /* one way to make this */
  1948. X        sp = sums;
  1949. X        while (i < 15) {
  1950. X        *np++ += *sp++;
  1951. X        i++;
  1952. X        }
  1953. X        sp = sums;
  1954. X        np = nsums;
  1955. X        i = 16;
  1956. X        while (--i)
  1957. X        *sp++ = *np++;
  1958. X    }
  1959. X    return sums[14];
  1960. X}
  1961. X
  1962. X
  1963. X
  1964. X/*
  1965. X * pairuns returns the number of points in the n card sorted hand
  1966. X * due to pairs and runs
  1967. X * this routine only works if n is strictly less than 6
  1968. X * sets the globals pairpoints and runpoints appropriately
  1969. X */
  1970. X
  1971. Xpairuns( h, n )
  1972. X
  1973. X    CARD        h[];
  1974. X    int            n;
  1975. X{
  1976. X    register  int        i;
  1977. X    int            runlength, runmult, lastmult, curmult;
  1978. X    int            mult1, mult2, pair1, pair2;
  1979. X    BOOLEAN            run;
  1980. X
  1981. X    run = TRUE;
  1982. X    runlength = 1;
  1983. X    mult1 = 1;
  1984. X    pair1 = -1;
  1985. X    mult2 = 1;
  1986. X    pair2 = -1;
  1987. X    curmult = runmult = 1;
  1988. X    for( i = 1; i < n; i++ )  {
  1989. X        lastmult = curmult;
  1990. X        if(  h[i].rank == h[i - 1].rank  )  {
  1991. X        if(  pair1 < 0  )  {
  1992. X            pair1 = h[i].rank;
  1993. X            mult1 = curmult = 2;
  1994. X        }
  1995. X        else  {
  1996. X            if(  h[i].rank == pair1  )  {
  1997. X            curmult = ++mult1;
  1998. X            }
  1999. X            else  {
  2000. X            if(  pair2 < 0  )  {
  2001. X                pair2 = h[i].rank;
  2002. X                mult2 = curmult = 2;
  2003. X            }
  2004. X            else  {
  2005. X                curmult = ++mult2;
  2006. X            }
  2007. X            }
  2008. X        }
  2009. X        if(  i == (n - 1)  &&  run  )  {
  2010. X            runmult *= curmult;
  2011. X        }
  2012. X        }
  2013. X        else  {
  2014. X        curmult = 1;
  2015. X        if(  h[i].rank == h[i - 1].rank + 1  )  {
  2016. X            if( run )  {
  2017. X            ++runlength;
  2018. X            }
  2019. X            else  {
  2020. X            if(  runlength < 3  )  {    /* only if old short */
  2021. X                run = TRUE;
  2022. X                runlength = 2;
  2023. X                runmult = 1;
  2024. X            }
  2025. X            }
  2026. X            runmult *= lastmult;
  2027. X        }
  2028. X        else  {
  2029. X            if( run )  runmult *= lastmult;    /* if just ended */
  2030. X            run = FALSE;
  2031. X        }
  2032. X        }
  2033. X    }
  2034. X    pairpoints = ichoose2[ mult1 ] + ichoose2[ mult2 ];
  2035. X    runpoints = ( runlength >= 3 ? runlength*runmult : 0 );
  2036. X    return(  pairpoints + runpoints  );
  2037. X}
  2038. X
  2039. X
  2040. X
  2041. X/*
  2042. X * pegscore tells how many points crd would get if played after
  2043. X * the n cards in tbl during pegging
  2044. X */
  2045. X
  2046. Xpegscore( crd, tbl, n, sum )
  2047. X
  2048. X    CARD        crd,  tbl[];
  2049. X    int            n;
  2050. X    int            sum;
  2051. X{
  2052. X    BOOLEAN            got[ RANKS ];
  2053. X    register  int        i, j, scr;
  2054. X    int            k, lo, hi;
  2055. X
  2056. X    sum += VAL( crd.rank );
  2057. X    if(  sum > 31  )  return( -1 );
  2058. X    if(  sum == 31  ||  sum == 15  )  scr = 2;
  2059. X    else                  scr = 0;
  2060. X    if(  !n  )  return( scr );
  2061. X    j = 1;
  2062. X    while(  ( crd.rank == tbl[n - j].rank )  &&  ( n - j >= 0 )  )  ++j;
  2063. X    if( j > 1 )  return( scr + ichoose2[j] );
  2064. X    if( n < 2 )  return( scr );
  2065. X    lo = hi = crd.rank;
  2066. X    for( i = 0; i < RANKS; i++ )  got[i] = FALSE;
  2067. X    got[ crd.rank ] = TRUE;
  2068. X    k = -1;
  2069. X    for( i = n - 1; i >= 0; --i )  {
  2070. X        if(  got[ tbl[i].rank ]  )  break;
  2071. X        got[ tbl[i].rank ] = TRUE;
  2072. X        if(  tbl[i].rank < lo  )  lo = tbl[i].rank;
  2073. X        if(  tbl[i].rank > hi  )  hi = tbl[i].rank;
  2074. X        for( j = lo; j <= hi; j++ )  if( !got[j] )  break;
  2075. X        if(  j > hi )  k = hi - lo + 1;
  2076. X    }
  2077. X    if(  k >= 3  )  return( scr + k );
  2078. X    else        return( scr );
  2079. X}
  2080. X
  2081. X
  2082. X
  2083. X/*
  2084. X * adjust takes a two card hand that will be put in the crib
  2085. X * and returns an adjusted normalized score for the number of
  2086. X * points such a crib will get.
  2087. X */
  2088. X
  2089. Xadjust( cb, tnv )
  2090. X
  2091. X    CARD        cb[], tnv;
  2092. X{
  2093. X    int            i,  c0,  c1;
  2094. X    long            scr;
  2095. X
  2096. X    c0 = cb[0].rank;
  2097. X    c1 = cb[1].rank;
  2098. X    if(  c0 > c1  )  {
  2099. X        i = c0;
  2100. X        c0 = c1;
  2101. X        c1 = i;
  2102. X    }
  2103. X    if(  cb[0].suit != cb[1].suit  )  scr = crbnescr[ RANKS*c0 + c1 ];
  2104. X    else                  scr = crbescr[ RANKS*c0 + c1 ];
  2105. X    if(  scr <= 0  )  {
  2106. X        printf( "\nADJUST: internal error %d %d\n",  c0, c1 );
  2107. X        exit( 93 );
  2108. X    }
  2109. X    return(  (scr + 29400)/58800  );
  2110. X}
  2111. X
  2112. X
  2113. X
  2114. END_OF_score.c
  2115. if test 9414 -ne `wc -c <score.c`; then
  2116.     echo shar: \"score.c\" unpacked with wrong size!
  2117. fi
  2118. # end of overwriting check
  2119. fi
  2120. echo shar: End of archive 1 \(of 2\).
  2121. cp /dev/null ark1isdone
  2122. MISSING=""
  2123. for I in 1 2 ; do
  2124.     if test ! -f ark${I}isdone ; then
  2125.     MISSING="${MISSING} ${I}"
  2126.     fi
  2127. done
  2128. if test "${MISSING}" = "" ; then
  2129.     echo You have unpacked both archives.
  2130.     rm -f ark[1-9]isdone
  2131. else
  2132.     echo You still need to unpack the following archives:
  2133.     echo "        " ${MISSING}
  2134. fi
  2135. ##  End of shell archive.
  2136. exit 0
  2137.